package com.bx.implatform.portal.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;

public class AESCryptor {
    // 使用AES/CBC/PKCS5Padding加密模式
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    private static final String AES = "AES";
    private static final int KEY_SIZE = 16; // AES-128需要16字节密钥

    /**
     * 加密方法
     *
     * @param plainText 明文
     * @param key43     43位密钥字符串
     * @return Base64编码的IV+密文（24位IV+加密内容）
     * @throws Exception 加密异常
     */
    public static String encrypt(String plainText, String key43) throws Exception {
        // 验证密钥长度
        if (key43.length() != 43) {
            throw new IllegalArgumentException("密钥必须为43位字符串");
        }
        // 生成16字节的AES密钥
        byte[] keyBytes = deriveKey(key43);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES);
        // 生成随机IV
        byte[] iv = new byte[16];
        new java.security.SecureRandom().nextBytes(iv);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        // 加密处理
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
        // 组合IV和密文并返回Base64
        byte[] combined = new byte[iv.length + encrypted.length];
        System.arraycopy(iv, 0, combined, 0, iv.length);
        System.arraycopy(encrypted, 0, combined, iv.length,
                encrypted.length);
        return Base64.getEncoder().encodeToString(combined);
    }

    /**
     * 解密方法
     *
     * @param cipherText Base64编码的IV+密文
     * @param key43      43位密钥字符串
     * @return 解密后的明文
     * @throws Exception 解密异常
     */
    public static String decrypt(String cipherText, String key43) throws Exception {
        if (key43.length() != 43) {
            throw new IllegalArgumentException("密钥必须为43位字符串");
        }
        // 解码Base64
        byte[] combined = Base64.getDecoder().decode(cipherText);
        if (combined.length < 16) {
            throw new IllegalArgumentException("密文过短，必须包含IV");
        }
        // 提取IV
        byte[] iv = new byte[16];
        System.arraycopy(combined, 0, iv, 0, iv.length);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        // 生成16字节的AES密钥
        byte[] keyBytes = deriveKey(key43);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES);
        // 解密处理
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] decrypted = cipher.doFinal(combined, 16, combined.length - 16);
        return new String(decrypted, StandardCharsets.UTF_8);
    }

    /**
     * 密钥派生函数：将43位字符串转换为16字节密钥
     * 17 / 20
     *
     * @param key43 43位原始密钥
     * @return 16字节AES密钥
     * @throws Exception 哈希异常
     */
    private static byte[] deriveKey(String key43) throws Exception {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(key43.getBytes(StandardCharsets.UTF_8));
        // 截取前16字节用于AES-128
        byte[] keyBytes = new byte[KEY_SIZE];
        System.arraycopy(hash, 0, keyBytes, 0, KEY_SIZE);
        return keyBytes;
    }

    // 测试方法
    public static void main(String[] args) throws Exception {
        // String key43 = "8Apyh2r6FDnDWJ6q3lHTDyjI63FrHsR1ZFfBCT7KNWr";
        // String original = "appKey=szjkIUrAVKH7IuIdkSg5&timestamp=1749462232&appSecret=VYhLd_4Vhq4NPuJ3PVLmPzc2l5ZKH9k9lG6phwt8A8x4k_ET9Ddsiz0fBfRQmPPO";
        // String encrypted = encrypt(original, key43);
        // System.out.println("加密结果: " + encrypted);
        // String decrypted = decrypt(encrypted, key43);
        // System.out.println("解密结果: " + decrypted);

        String s1 = "appKey=szjkIUrAVKH7IuIdkSg5&deptId=1930443230457155585&timestamp=1749605278&appSecret=VYhLd_4Vhq4NPuJ3PVLmPzc2l5ZKH9k9lG6phwt8A8x4k_ET9Ddsiz0fBfRQmPPO";
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(s1.getBytes());
        System.out.println("部门" + org.apache.tomcat.util.codec.binary.Base64.encodeBase64String(digest));
    }
}